'''
Created on Jun 12, 2011

@author: Herio Mortis
'''

from Tkinter import *
import serial
from OSESerialComs import *
import platform
import glob

class OSEMicroSettingsDialog(object):
    '''
    Class: OSEMicroSettingsDialog
    
    Description:
        Creates a window where the user can change the COM port settings
        
    '''
    

    serialComs = OSESerialComs()
 
    
    def __init__(self, parent, serialComs):
        '''
        Constructor
        '''
        self.serialComs = serialComs
        settings_window = self.settings_window = Toplevel(parent)
        
        '''
        create baudrate drop down
        '''
        self.baudrate_label = Label(settings_window, text = "Baudrate")
        self.baudrate_label.grid(column = 0, row = 0, stick = W)
        
        self.baudrate = StringVar()
        self.baudrate.set(str(serialComs.getBaudrate()))
        baudrateMenu = OptionMenu(settings_window, self.baudrate, "9600","19200","38400", "57600", "115200")
        baudrateMenu.grid(column = 1, row = 0, stick = W)
        
        '''
        create parity drop down
        '''
        self.parity_label = Label(settings_window, text = "Parity")
        self.parity_label.grid(column = 0, row = 1, stick = W)
        
        self.parity = StringVar()
        self.parity.set(str(serialComs.getParity()))
        parityMenu = OptionMenu(settings_window, self.parity, "even", "odd", "none")
        parityMenu.grid(column = 1, row = 1, stick = W)
        
        
        '''
        create data bits drop down
        '''
        self.databits_label = Label(settings_window, text = "Databits")
        self.databits_label.grid(column = 0, row = 2, stick = W)

        self.dataBits = StringVar()
        self.dataBits.set(str(serialComs.getBytesize()))
        dataBitsMenu = OptionMenu(settings_window, self.dataBits, "5", "6", "7", "8")
        dataBitsMenu.grid(column = 1, row = 2, stick = W)

        '''
        create stop bits drop down
        '''     
        self.stopbits_label = Label(settings_window, text = "Stopbits")
        self.stopbits_label.grid(column = 0, row = 3, stick = W)

        self.stopBits = StringVar()  
        self.stopBits.set(str(serialComs.getStopbits()))
        stopBitsMenu = OptionMenu(settings_window, self.stopBits, "1", "1.5", "2")
        stopBitsMenu.grid(column = 1, row = 3, stick = W)
        
        
        '''
        create flow control drop down
        '''
        self.flowcontrol_label = Label(settings_window, text = "Flow Control")
        self.flowcontrol_label.grid(column = 0, row = 4, stick = W)
        
        self.flowcontrol = StringVar()
        self.flowcontrol.set(str(serialComs.getFlowControl()))
        flowcontrolMenu = OptionMenu(settings_window, self.flowcontrol, "True", "False")
        flowcontrolMenu.grid(column = 1, row = 4, stick = W)
        
        
        '''
        create available com ports drop down
        '''
        
        optionTuple = ("",)
        #defaultOption = StringVar()
        #optionMenuWidget = apply(OptionMenu, (optionFrame, defaultOption) + optionTuple)
        '''
        self.currentComPort = StringVar()
        self.currentComPort.set(serialComs.getPort())
        comPortMenu = apply(OptionMenu, (settings_window, self.currentComPort) + optionTuple)
        comPortMenu["menu"].delete(0, END)
        for portname in self.scanComPorts():
            comPortMenu["menu"].add_command(label=portname, command=lambda temp = portname: comPortMenu.setvar(comPortMenu.cget("testvariable"), value = temp))
            #optionMenuWidget["menu"].add_command(label=i, command=lambda temp = i: optionMenuWidget.setvar(optionMenuWidget.cget("textvariable"), value = temp))
        
        comPortMenu.pack()
        '''
        
        self.comport_label = Label(settings_window, text = "COM Port")
        self.comport_label.grid(column = 0, row = 5, stick = W)

        self.currentComPort = StringVar()
        self.currentComPort.set(serialComs.getPort())
        '''
        comPortMenu = OptionMenu(settings_window, self.currentComPort, '')
        comPortMenu["menu"].delete(0)
        for portname in self.scanComPorts():
            comPortMenu["menu"].add_command(portname)
        
        comPortMenu.pack()
        '''
        
        comPortEntry = Entry(settings_window, textvariable = self.currentComPort)
        comPortEntry.grid(column = 1, row = 5, stick = W)
        
        okButton = Button(settings_window, text="OK", command=self.ok)
        okButton.grid(column = 0, row = 6)
        
        applyButton = Button(settings_window, text="Apply", command = self.applySettings)
        applyButton.grid(column = 1, row = 6)
        
        cancelButton = Button(settings_window, text="Cancel", command = self.cancel)
        cancelButton.grid(column = 2, row = 6)
        return
    
    def applySettings(self):
        '''
        Function: applySettings
        
        Description:
            Applies all changes made to the COM port settings into a OSESerialComs object.
        
        Returns:
            Nothing
        '''
        self.serialComs.setBaudrate(int(self.baudrate.get()))
        self.serialComs.setBytesize(self.dataBits.get())
        if self.flowcontrol.get() == "True":
            self.serialComs.setFlowControl(True)
        elif self.flowcontrol.get() == "False":
            self.serialComs.setFlowControl(False)
        self.serialComs.setParity(self.parity.get())
        self.serialComs.setPort(self.currentComPort.get())
        self.serialComs.setStopbits(self.stopBits.get())
        return
    
    def ok(self):
        '''
        Function: ok
        
        Description:
            Applies settings and closes window.
            
        Returns:
            Nothing
        '''
        
        self.applySettings()
        self.settings_window.destroy()
        return
    
    def cancel(self):
        '''
        Function: cancel
        
        Description:
            Discards any unsaved changes and closes the window.
        
        Returns:
            Nothing
        '''
        self.settings_window.destroy()
        
    def scanComPorts(self):
        """
        Function: scanComPorts
        Description:
            Scans the computer for available com ports and returns a list of the 
            port numbers and names.
            **Deprecated**
        Returns: a list of tuples (port number, port name) (int, str)
        """
        availablePorts = []
        if platform.system() == 'Linux':
            Ports = glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*')
            return availablePorts
        else:    
                
            
            for portNumber in range(256):
                try:
                    testport = serial.Serial(portNumber)
                    availablePorts.append( testport.portstr)
                    testport.close()   # explicit close 'cause of delayed GC in java
                except serial.SerialException:
                    pass
            return availablePorts
    
    
        def _newBaudRate(self, newBaudRate):
            '''
            
            Set new baud rate in serial object
            '''
            print "new baud rate", newBaudRate
             
    